package ru.spb.osll.myfit.client.widget;

import java.util.LinkedList;
import java.util.List;

import ru.spb.osll.myfit.client.PageMode;
import ru.spb.osll.myfit.client.event.PageEvent;
import ru.spb.osll.myfit.client.event.PageEvent.PageEventType;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.ProgressCounts;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Page widget.
 * 
 */
public class PageWidget extends Composite implements PageEventListener {

  private PageElementWidgetFactory m_pageElementWidgetFactory;

  List<PageEventListener> m_listeners = new LinkedList<PageEventListener>();
  /**
   * Main panel. All page elements will be added in it.
   */
  private VerticalPanel m_rootPanel;
  private PageMode m_mode = PageMode.VIEW;

  private String m_pagePath = "";
  private PageExecutingListenerImpl executingListener;

  public PageWidget(GWTWidgetFactory gwtWidgetFactory) {
    m_pageElementWidgetFactory = new PageElementWidgetFactory(gwtWidgetFactory);
    m_rootPanel = gwtWidgetFactory.createVerticalPanel();
    m_rootPanel.setSpacing(20);
    m_rootPanel.setStyleName("table-panel");
    m_rootPanel.setHeight("100%");
    m_rootPanel.setWidth("100%");
    m_rootPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
    m_rootPanel.setLayoutData(gwtWidgetFactory.createScrollPanel());
    initWidget(m_rootPanel);
  }

  public void addPageElementWidget(PageElement pageElement) {
    PageElementWidget pageElementWidget = m_pageElementWidgetFactory.getPageElementWidget(pageElement);
    if (pageElementWidget != null) {
      pageElementWidget.setPageEventListener(this);
      pageElementWidget.setMode(m_mode);
      m_rootPanel.add(pageElementWidget);
    }
  }

  public void addPageElementWidget(PageElement pageElement, int index) {
    PageElementWidget pageElementWidget = m_pageElementWidgetFactory.getPageElementWidget(pageElement);
    if (pageElementWidget != null) {
      pageElementWidget.setPageEventListener(this);
      pageElementWidget.setMode(m_mode);
      m_rootPanel.insert(pageElementWidget, index);
    }
  }

  public void clear() {
    m_rootPanel.clear();
  }

  public ProgressCounts getCounts() {
    if (executingListener != null) {
      return executingListener.getCounts();
    }
    return new ProgressCounts();
  }

  public boolean getState() {
    if (executingListener != null) {
      return executingListener.getFinished();
    }
    return false;
  }

  public void setMode(PageMode mode) {
    m_mode = mode;
    int widgetCount = m_rootPanel.getWidgetCount();
    for (int i = 0; i < widgetCount; i++) {
      PageElementWidget pageElemnt = (PageElementWidget) m_rootPanel.getWidget(i);
      pageElemnt.setMode(m_mode);
    }
  }

  public PageElementWidget getElementWidget(int index) {
    return (PageElementWidget) m_rootPanel.getWidget(index);
  }

  public int getElementWidgetCount() {
    return m_rootPanel.getWidgetCount();
  }

  public Page getPage() {
    Page page = new Page();
    int size = m_rootPanel.getWidgetCount();
    for (int i = 0; i < size; i++) {
      PageElementWidget pageElementWidget = (PageElementWidget) m_rootPanel.getWidget(i);
      PageElement pageElement = pageElementWidget.save();
      if (pageElement != null) {
        page.insert(pageElement);
      }
    }
    return page;
  }

  public void deletePageElemetWidget(PageElementWidget elmenetToDelete) {
    m_rootPanel.remove(elmenetToDelete);
  }

  public void insertPageElemnt(PageElementWidget selectedWidget, PageElement elementToInsert, boolean isBefore) {
    int palce = m_rootPanel.getWidgetIndex(selectedWidget);// m_pagesWidgets.indexOf(selectedWidget);
    if (palce == -1) {
      addPageElementWidget(elementToInsert);
    } else {
      if (!isBefore) {
        palce++;
      }
      addPageElementWidget(elementToInsert, palce);
    }
  }

  public void setOpen(boolean isOpen) {
    int pageWidgetsCount = m_rootPanel.getWidgetCount();
    for (int i = 0; i < pageWidgetsCount; i++) {
      PageElementWidget elementWidget = (PageElementWidget) m_rootPanel.getWidget(i);
      elementWidget.setOpen(isOpen);
    }
  }

  @Override
  public void actionPerformed(PageEvent event) {
    if (event.getType() == PageEventType.DELETE_PAGE_ELEMENT) {
      deletePageElemetWidget(event.getSource());

    } else {
      for (PageEventListener listener : m_listeners) {
        PageEvent newEvent = new PageEvent(event.getType(), event.isBefore(), event.getSource(), this);
        listener.actionPerformed(newEvent);
      }
    }
  }

  public int getWidgetCount() {
    return m_rootPanel.getWidgetCount();
  }

  public PageElementWidget getPageElementWidget(int index) {
    return (PageElementWidget) m_rootPanel.getWidget(index);
  }

  public void removeWidget(int position) {
    m_rootPanel.remove(position);
  }

  public void addPageEventListener(PageEventListener listener) {
    m_listeners.add(listener);
  }

  public void removePageEventListener(PageEventListener listener) {
    m_listeners.remove(listener);
  }

  public String getPagePath() {
    return m_pagePath;
  }

  public void setPagePath(String pagePath) {
    m_pagePath = pagePath;
  }

}
